package services

import (
	"bufio"
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"strings"
	"time"

	"demo2/config"
)

// min 返回两个整数中的较小值
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// DeepSeekMessage DeepSeek API消息格式
type DeepSeekMessage struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

// DeepSeekRequest DeepSeek API请求格式
type DeepSeekRequest struct {
	Model       string            `json:"model"`
	Messages    []DeepSeekMessage `json:"messages"`
	Temperature float64           `json:"temperature,omitempty"`
	MaxTokens   int               `json:"max_tokens,omitempty"`
	Stream      bool              `json:"stream,omitempty"`
}

// DeepSeekResponse DeepSeek API响应格式
type DeepSeekResponse struct {
	ID      string `json:"id"`
	Object  string `json:"object"`
	Created int64  `json:"created"`
	Model   string `json:"model"`
	Choices []struct {
		Index   int `json:"index"`
		Message struct {
			Role    string `json:"role"`
			Content string `json:"content"`
		} `json:"message"`
		FinishReason string `json:"finish_reason"`
	} `json:"choices"`
	Usage struct {
		PromptTokens     int `json:"prompt_tokens"`
		CompletionTokens int `json:"completion_tokens"`
		TotalTokens      int `json:"total_tokens"`
	} `json:"usage"`
}

// DeepSeekStreamResponse 流式响应格式
type DeepSeekStreamResponse struct {
	ID      string `json:"id"`
	Object  string `json:"object"`
	Created int64  `json:"created"`
	Model   string `json:"model"`
	Choices []struct {
		Index int `json:"index"`
		Delta struct {
			Role    string `json:"role,omitempty"`
			Content string `json:"content,omitempty"`
		} `json:"delta"`
		FinishReason *string `json:"finish_reason"`
	} `json:"choices"`
}

// LLMService LLM服务
type LLMService struct {
	config     config.DeepSeekConfig
	httpClient *http.Client
	mcpClient  *MCPClient
}

// NewLLMService 创建新的LLM服务
func NewLLMService(cfg config.DeepSeekConfig) *LLMService {
	return &LLMService{
		config: cfg,
		httpClient: &http.Client{
			Timeout: 60 * time.Second,
		},
		mcpClient: NewMCPClient(),
	}
}

// Close 关闭服务
func (l *LLMService) Close() error {
	return l.mcpClient.Stop()
}

// GenerateResponse 生成回复
func (l *LLMService) GenerateResponse(ctx context.Context, messages []DeepSeekMessage) (string, error) {
	log.Printf("[LLM-SERVICE] 🤖 收到生成回复请求，消息数量: %d", len(messages))
	
	// 获取最后一条用户消息
	var lastUserMessage string
	for i := len(messages) - 1; i >= 0; i-- {
		if messages[i].Role == "user" {
			lastUserMessage = messages[i].Content
			break
		}
	}
	
	log.Printf("[LLM-SERVICE] 📝 最后一条用户消息: %s", lastUserMessage)

	// 分析用户意图
	log.Printf("[LLM-SERVICE] 🔍 开始分析用户意图...")
	intent, param := l.mcpClient.AnalyzeUserIntent(lastUserMessage)
	log.Printf("[LLM-SERVICE] 🎯 意图分析结果: intent=%s, param=%s", intent, param)

	switch intent {
	case "time":
		log.Printf("[LLM-SERVICE] 🕐 处理时间查询请求...")
		return l.handleTimeQuery(ctx, param)
	case "calculate":
		log.Printf("[LLM-SERVICE] 🧮 处理计算请求...")
		return l.handleCalculation(ctx, param)
	default:
		log.Printf("[LLM-SERVICE] 💬 处理普通聊天请求...")
		return l.handleChatQuery(ctx, messages)
	}
}

// GenerateStreamResponse 生成流式回复
func (l *LLMService) GenerateStreamResponse(ctx context.Context, messages []DeepSeekMessage, responseChan chan<- string) error {
	defer close(responseChan)

	// 获取最后一条用户消息
	var lastUserMessage string
	for i := len(messages) - 1; i >= 0; i-- {
		if messages[i].Role == "user" {
			lastUserMessage = messages[i].Content
			break
		}
	}

	// 分析用户意图
	intent, param := l.mcpClient.AnalyzeUserIntent(lastUserMessage)

	switch intent {
	case "time":
		result, err := l.handleTimeQuery(ctx, param)
		if err != nil {
			responseChan <- fmt.Sprintf("查询时间时出现错误：%v", err)
		} else {
			// 模拟流式输出
			words := strings.Fields(result)
			for _, word := range words {
				select {
				case <-ctx.Done():
					return ctx.Err()
				case responseChan <- word + " ":
					time.Sleep(50 * time.Millisecond) // 模拟打字效果
				}
			}
		}
		return nil

	case "calculate":
		result, err := l.handleCalculation(ctx, param)
		if err != nil {
			responseChan <- fmt.Sprintf("计算时出现错误：%v", err)
		} else {
			// 模拟流式输出
			responseChan <- fmt.Sprintf("计算结果：%s = %s", param, result)
		}
		return nil

	default:
		return l.handleChatStreamQuery(ctx, messages, responseChan)
	}
}

// handleTimeQuery 处理时间查询
func (l *LLMService) handleTimeQuery(ctx context.Context, location string) (string, error) {
	log.Printf("[LLM-SERVICE] 🕐 开始处理时间查询，地点: %s", location)
	
	result, err := l.mcpClient.GetTime(ctx, location)
	if err != nil {
		log.Printf("[LLM-SERVICE] ❌ 时间查询失败: %v", err)
		return "", fmt.Errorf("查询%s时间失败: %v", location, err)
	}
	
	log.Printf("[LLM-SERVICE] ✅ 时间查询成功，结果: %s", result)
	return result, nil
}

// handleCalculation 处理计算请求
func (l *LLMService) handleCalculation(ctx context.Context, expression string) (string, error) {
	log.Printf("[LLM-SERVICE] 🧮 开始处理计算请求，表达式: %s", expression)
	
	result, err := l.mcpClient.Calculate(ctx, expression)
	if err != nil {
		log.Printf("[LLM-SERVICE] ❌ 计算失败: %v", err)
		return "", fmt.Errorf("计算%s失败: %v", expression, err)
	}
	
	finalResult := fmt.Sprintf("%s = %s", expression, result)
	log.Printf("[LLM-SERVICE] ✅ 计算成功，结果: %s", finalResult)
	return finalResult, nil
}

// handleChatQuery 处理普通聊天
func (l *LLMService) handleChatQuery(ctx context.Context, messages []DeepSeekMessage) (string, error) {
	log.Printf("[LLM-SERVICE] 💬 开始处理普通聊天，消息数量: %d", len(messages))
	
	// 添加系统提示
	systemMessage := DeepSeekMessage{
		Role: "system",
		Content: `你是一个智能助手，可以帮助用户查询时间和进行计算。

你有以下能力：
1. 查询世界各地的当前时间 - 当用户询问某地时间时，我会为你调用时间查询工具
2. 进行数学计算 - 当用户需要计算时，我会为你调用计算工具

支持的地点包括：北京、上海、东京、纽约、伦敦、巴黎、洛杉矶、悉尼、新加坡、香港、台北、首尔、莫斯科、迪拜、孟买、曼谷、雅加达、马尼拉、吉隆坡、河内等。

支持的计算包括：基本四则运算(+、-、*、/)、平方根sqrt()、幂运算pow()等。

请用友好、专业的语气回答用户的问题。`,
	}

	allMessages := append([]DeepSeekMessage{systemMessage}, messages...)
	log.Printf("[LLM-SERVICE] 📤 准备调用DeepSeek API，总消息数: %d", len(allMessages))

	request := DeepSeekRequest{
		Model:       "deepseek-chat",
		Messages:    allMessages,
		Temperature: 0.7,
		MaxTokens:   2000,
		Stream:      false,
	}

	result, err := l.callDeepSeekAPI(ctx, request)
	if err != nil {
		log.Printf("[LLM-SERVICE] ❌ DeepSeek API调用失败: %v", err)
		return "", err
	}
	
	log.Printf("[LLM-SERVICE] ✅ DeepSeek API调用成功，响应长度: %d", len(result))
	return result, nil
}

// handleChatStreamQuery 处理流式聊天
func (l *LLMService) handleChatStreamQuery(ctx context.Context, messages []DeepSeekMessage, responseChan chan<- string) error {
	// 添加系统提示
	systemMessage := DeepSeekMessage{
		Role: "system",
		Content: `你是一个智能助手，可以帮助用户查询时间和进行计算。

你有以下能力：
1. 查询世界各地的当前时间 - 当用户询问某地时间时，我会为你调用时间查询工具
2. 进行数学计算 - 当用户需要计算时，我会为你调用计算工具

支持的地点包括：北京、上海、东京、纽约、伦敦、巴黎、洛杉矶、悉尼、新加坡、香港、台北、首尔、莫斯科、迪拜、孟买、曼谷、雅加达、马尼拉、吉隆坡、河内等。

支持的计算包括：基本四则运算(+、-、*、/)、平方根sqrt()、幂运算pow()等。

请用友好、专业的语气回答用户的问题。`,
	}

	allMessages := append([]DeepSeekMessage{systemMessage}, messages...)

	request := DeepSeekRequest{
		Model:       "deepseek-chat",
		Messages:    allMessages,
		Temperature: 0.7,
		MaxTokens:   2000,
		Stream:      true,
	}

	return l.callDeepSeekStreamAPI(ctx, request, responseChan)
}

// callDeepSeekAPI 调用DeepSeek API
func (l *LLMService) callDeepSeekAPI(ctx context.Context, request DeepSeekRequest) (string, error) {
	log.Printf("[DEEPSEEK-API] 🚀 开始调用DeepSeek API，模型: %s", request.Model)
	
	requestBody, err := json.Marshal(request)
	if err != nil {
		log.Printf("[DEEPSEEK-API] ❌ 序列化请求失败: %v", err)
		return "", fmt.Errorf("序列化请求失败: %v", err)
	}
	
	log.Printf("[DEEPSEEK-API] 📤 发送HTTP请求到: %s", l.config.BaseURL+"/chat/completions")

	req, err := http.NewRequestWithContext(ctx, "POST", l.config.BaseURL+"/chat/completions", bytes.NewBuffer(requestBody))
	if err != nil {
		log.Printf("[DEEPSEEK-API] ❌ 创建HTTP请求失败: %v", err)
		return "", fmt.Errorf("创建请求失败: %v", err)
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+l.config.APIKey)
	log.Printf("[DEEPSEEK-API] 🔑 设置请求头完成")

	resp, err := l.httpClient.Do(req)
	if err != nil {
		log.Printf("[DEEPSEEK-API] ❌ 发送HTTP请求失败: %v", err)
		return "", fmt.Errorf("发送请求失败: %v", err)
	}
	defer resp.Body.Close()

	log.Printf("[DEEPSEEK-API] 📥 收到HTTP响应，状态码: %d", resp.StatusCode)

	responseBody, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Printf("[DEEPSEEK-API] ❌ 读取响应体失败: %v", err)
		return "", fmt.Errorf("读取响应失败: %v", err)
	}

	if resp.StatusCode != http.StatusOK {
		log.Printf("[DEEPSEEK-API] ❌ API请求失败，状态码: %d, 响应: %s", resp.StatusCode, string(responseBody))
		return "", fmt.Errorf("API请求失败，状态码: %d, 响应: %s", resp.StatusCode, string(responseBody))
	}

	var response DeepSeekResponse
	if err := json.Unmarshal(responseBody, &response); err != nil {
		log.Printf("[DEEPSEEK-API] ❌ 解析响应失败: %v", err)
		return "", fmt.Errorf("解析响应失败: %v", err)
	}

	if len(response.Choices) == 0 {
		log.Printf("[DEEPSEEK-API] ❌ 没有收到有效响应")
		return "", fmt.Errorf("没有收到有效响应")
	}

	result := response.Choices[0].Message.Content
	log.Printf("[DEEPSEEK-API] ✅ API调用成功，响应长度: %d, Token使用: %d", len(result), response.Usage.TotalTokens)
	log.Printf("[DEEPSEEK-API] 📝 响应内容预览: %s...", result[:min(100, len(result))])

	return result, nil
}

// callDeepSeekStreamAPI 调用DeepSeek流式API
func (l *LLMService) callDeepSeekStreamAPI(ctx context.Context, request DeepSeekRequest, responseChan chan<- string) error {
	requestBody, err := json.Marshal(request)
	if err != nil {
		return fmt.Errorf("序列化请求失败: %v", err)
	}

	req, err := http.NewRequestWithContext(ctx, "POST", l.config.BaseURL+"/chat/completions", bytes.NewBuffer(requestBody))
	if err != nil {
		return fmt.Errorf("创建请求失败: %v", err)
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+l.config.APIKey)
	req.Header.Set("Accept", "text/event-stream")

	resp, err := l.httpClient.Do(req)
	if err != nil {
		return fmt.Errorf("发送请求失败: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("API请求失败，状态码: %d, 响应: %s", resp.StatusCode, string(body))
	}

	reader := bufio.NewReader(resp.Body)
	for {
		select {
		case <-ctx.Done():
			return ctx.Err()
		default:
		}

		line, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				break
			}
			return fmt.Errorf("读取流式响应失败: %v", err)
		}

		line = strings.TrimSpace(line)
		if line == "" || line == "data: [DONE]" {
			continue
		}

		if strings.HasPrefix(line, "data: ") {
			data := strings.TrimPrefix(line, "data: ")
			
			var streamResp DeepSeekStreamResponse
			if err := json.Unmarshal([]byte(data), &streamResp); err != nil {
				continue // 跳过无法解析的行
			}

			if len(streamResp.Choices) > 0 {
				content := streamResp.Choices[0].Delta.Content
				if content != "" {
					select {
					case <-ctx.Done():
						return ctx.Err()
					case responseChan <- content:
					}
				}

				if streamResp.Choices[0].FinishReason != nil {
					break
				}
			}
		}
	}

	return nil
}
